<?php

namespace Kangcg\Tencent\Library\V3;

use Kangcg\Application\File\File;
use Kangcg\Application\File\FileZip;
use Kangcg\Tencent\Library\免费证书申请;

/**
 * 证书相关
 */
trait Ssl
{
    /**
     * @param string $DvAuthMethod 验证方式：DNS_AUTO = 自动DNS验证，DNS = 手动DNS验证，FILE = 文件验证。
     * @param String $DomainName 域名。
     * @param string $Alias 备注名称。
     * @param string $OldCertificateId 原证书 ID，用于重新申请。
     * @param string $ContactEmail
     * @param string $ContactPhone
     * @param array $data
     * @return bool|string 成功返回 CertificateId
     * @var 免费证书申请
     * @see https://cloud.tencent.com/document/api/400/41678
     */
    public function applyCertificate(string $DomainName, string $DvAuthMethod = 'FILE', string $Alias = null, string $OldCertificateId = null, string $ContactEmail = null, string $ContactPhone = null, array $data = [])
    {
        $this->region = null;
        $data['DvAuthMethod'] = $DvAuthMethod;
        $data['DomainName'] = $DomainName;
        $data['Alias'] = $Alias;
        $data['OldCertificateId'] = $OldCertificateId;
        $data['ContactEmail'] = $ContactEmail;
        $data['ContactPhone'] = $ContactPhone;
        if (!$result = $this->httpRequest(array_filter($data), self::SSL_URL, __FUNCTION__, '2019-12-05')) {
            return false;
        }

        return isset($result['Response']['CertificateId']) ? $result['Response']['CertificateId'] : false;
    }

    /**
     * @vasr 获取证书信息
     * @param string $certificateId
     * @return false|mixed
     */
    public function describeCertificate(string $certificateId)
    {
        $data['CertificateId'] = $certificateId;
        if (!$result = $this->httpRequest(array_filter($data), self::SSL_URL, __FUNCTION__, '2019-12-05')) {
            return false;
        }

        return $result['Response'];
    }

    /**
     * @param string $CertificateId
     * @return bool
     * @var 主动触发证书验证
     */
    public function completeCertificate(string $CertificateId)
    {
        $data['CertificateId'] = $CertificateId;
        if (!$this->httpRequest(array_filter($data), self::SSL_URL, __FUNCTION__, '2019-12-05')) {
            return false;
        }

        return true;
    }
    /**
     * @param string $CertificateId
     * @param array $certPaths 存储目标 ['./aa/aaa.crt','./bb/aaa.pem']
     * @param string $tmpPath
     * @param string $type
     * @return bool
     */
    public function deployCertificate(string $CertificateId = '', array $certPaths, $tmpPath = './', $type = self::CERT_TYPE_NGINX)
    {
        if(false === ($tmpPath = realpath($tmpPath))){
            $tmpPath = realpath('./');
        }

        if(!$filePath = $this->downloadCertificate($CertificateId, $tmpPath)){
            return false;
        }

        $zipPath = $tmpPath . DIRECTORY_SEPARATOR . $CertificateId;
        $zip = new FileZip();
        if(!$zip->unzip($filePath, $zipPath)){
            return $this->setErrors(-1, "文件解压失败！");
        }

        $filePath = $zipPath . DIRECTORY_SEPARATOR . $type;
        if(!file_exists($filePath)){
            return $this->setErrors(-1, $type . "没有该类型的证书");
        }

        $dir = opendir($filePath);
        while ($file = readdir($dir)) {
            if ($file == '.' || $file == '..') {
                continue;
            }

            $ext = explode('.', trim($file));
            $ext = array_pop($ext);

            foreach ($certPaths as $certPath) {
                if(strpos($certPath, $ext) > 0 && File::move($filePath . DIRECTORY_SEPARATOR . $file, $certPath) === false){
                    return $this->setErrors(-1, "文件移动失败！");
                }
            }
        }

        return true;
    }

    /**
     * @vasr 下载证书
     * @param string $CertificateId
     * @param string $filePath 保存地址
     * @return bool|string 返回文件地址
     */
    public function downloadCertificate(string $CertificateId, string $filePath = './')
    {
        if (false === ($filePath = realpath($filePath))) {
            $filePath = realpath('./');
        }

        $data['CertificateId'] = $CertificateId;
        if (!$result = $this->httpRequest(array_filter($data), self::SSL_URL, __FUNCTION__, '2019-12-05')) {
            return false;
        }

        $filename = $filePath . DIRECTORY_SEPARATOR . $CertificateId . '.zip';
        if (!file_put_contents($filename, base64_decode($result['Response']['Content']))) {
            return $this->setErrors(-1, "保存失败！");
        }

        return $filename;
    }

    /**
     * @vasr 证书资料提交
     * @param string $CertificateId
     * @return bool|mixed
     */
    public function commitCertificateInformation(string $CertificateId)
    {
        $data['CertificateId'] = $CertificateId;
        if (!$result = $this->httpRequest(array_filter($data), self::SSL_URL, __FUNCTION__, '2019-12-05')) {
            return false;
        }

        return $result;
    }

    /**
     * @param string $certificateId
     * @return false|array ['path' => 文件存放目录, 'filename' => '文件名称', 'content' => 文件保存内容]
     * @var 获取验证文件进行
     */
    public function getCertificateDvAuthDetail(string $certificateId)
    {
        if (!$result = $this->describeCertificate($certificateId)) {
            return false;
        }

        $data = [];
        foreach ($result['DvAuthDetail']['DvAuths'] as $dvAuth) {
            $data[$dvAuth['Domain']] = [
                'path' => $dvAuth['DvAuthPath'],
                'filename' => $dvAuth['DvAuthPath'] . $dvAuth['DvAuthKey'],
                'content' => $dvAuth['DvAuthValue'],
            ];
        }

        return $data;
    }

    /**
     * @vasr 判断证书是否颁发
     * @param string $certificateId
     * @return bool
     */
    public function issueCertificate(string $certificateId)
    {
        if (!$result = $this->describeCertificate($certificateId)) {
            return false;
        }

        if ($result['Status'] != 1) {
            return $this->setErrors($result['Status'], $result['StatusMsg']);
        }

        return true;
    }
}
